package com.future.common.interceptor;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

import com.future.common.annotation.Async;
import com.future.common.utils.async.AsyncUtil;
import com.jfinal.aop.Interceptor;
import com.jfinal.aop.Invocation;

public class AsyncInterceptor implements Interceptor {
	@Override
	public void intercept(Invocation inv) {
		if (inv.getMethod().getAnnotation(Async.class) != null) {
			if (inv.getMethod().getReturnType().equals(Void.TYPE)) {
				com.future.common.utils.async.AsyncUtil.process(() -> inv.invoke());

			} else {
				@SuppressWarnings("unchecked")
				Future<Object> future = AsyncUtil.get(() -> {
					inv.invoke();
					Object result;
					try {
						result = ((Future<Object>) inv.getReturnValue()).get();
					} catch (InterruptedException | ExecutionException e) {
						throw new RuntimeException(e);
					}
					return result;
				});
				inv.setReturnValue(future);
			}
			return;
		} else {
			inv.invoke();
		}
	}

}
